package hammersmith.local.ui.cui;

import hammersmith.local.exceptions.ArticleNotFoundException;
import hammersmith.local.exceptions.EmptyCartException;
import hammersmith.local.exceptions.StockTooLowException;
import hammersmith.local.exceptions.WrongInputException;
import hammersmith.local.exceptions.WrongMinCountException;
import hammersmith.local.management.LogManagement;
import hammersmith.local.management.ShopManagement;
import hammersmith.local.ui.gui.LoginMask;
import hammersmith.local.valueobjects.Article;
import hammersmith.local.valueobjects.Customer;
import hammersmith.local.valueobjects.Employee;
import hammersmith.local.valueobjects.Invoice;
import hammersmith.local.valueobjects.Log;
import hammersmith.local.valueobjects.MassArticle;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.Timestamp;
import java.util.ArrayList;

/**
 * Shop-Klasse (incl. Main)
 * 
 * @author hammersmith
 * 
 */
public class MainShop {
	ShopManagement shopManager;
	BufferedReader console;

	// Konstruktor
	public MainShop() {
		shopManager = new ShopManagement("","");
		shopManager = shopManager.loadDB();
		console = new BufferedReader(new InputStreamReader(System.in));
	}

	/**
	 * CUI-Methode zur Auswahl ob Mitarbeiter- oder Kundenlogin
	 */
	public void selectUserType() {
		boolean ok = false;
		System.out.println("Willkommen bei " + shopManager.getName());
		System.out
				.println("Als was moechten sie sich einloggen? \n Mitarbeiter=M \n Kunde=K \n Registrieren=R");
		System.out.println("");
		System.out.print("Wahl:");
		// Durchlauf bis zu einem Ergebnis
		while (!ok) {
			String input = "";
			try {
				input = console.readLine();
			} catch (IOException e) {
				e.printStackTrace();
			}
			// Ueberpruefung welcher Input eingetragen wurde
			if (input.equalsIgnoreCase("m")) {
				ok = true;
				loginEmployee();
			} else if (input.equalsIgnoreCase("k")) {
				ok = true;
				loginCustomer();
			} else if (input.equalsIgnoreCase("r")) {
				ok = true;
				registerCustomer();
			} else {
				System.out.println("Falsche Eingabe");
				System.out.print("Wahl:");
			}
		}
	}

	/**
	 * CUI-Methode zum registrieren eines neuen Kunden
	 */
	public void registerCustomer() {
		int ok = 0;
		do {
			try {
				System.out.println("Name:");
				String name = console.readLine();
				System.out.println("Vorname");
				String firstname = console.readLine();
				System.out.println("Strasse:");
				String street = console.readLine();
				System.out.println("Postleitzahl:");
				String zip = console.readLine();
				System.out.println("City:");
				String city = console.readLine();
				System.out.print("E-Mail:");
				String mail = console.readLine();
				System.out.print("Passwort:");
				String pw = console.readLine();
				// Erstellung eines neuen Kunden-Objekts

				shopManager.addNewCustomer(name, firstname, street, zip, city,
						mail, pw);

				// Wenn der Rueckgabewert true ist -> Ausgabe der errechneten ID
				// Abschliessen der Registrierung
				if (ok != 0) {
					System.out.println("Die Registrierung war erfolgreich!");
					System.out.println("Ihre ID ist: -" + ok + "-");
					selectUserType();
				}
			} catch (Exception e) {
				System.out
						.println("Leider war eine registrierung nicht erfolgreich!");
			}
		} while (ok != 0);
	}

	/**
	 * CUI-Methode zur Ueberpruefung der Logindaten eines Kunden und
	 * weiterleiten in das Kundenmenue
	 */
	public void loginCustomer() {
		Customer found = null;
		String user = "";
		String pw = "";
		while (found == null) {
			System.out.println("Bitte KundenID eingeben:");
			try {
				user = console.readLine();
			} catch (IOException e) {
				e.printStackTrace();
			}
			System.out.println("Bitte Passwort eingeben:");
			try {
				pw = console.readLine();
			} catch (IOException e) {
				e.printStackTrace();
			}

			found = shopManager.loginCustomer(user, pw);

			// Wenn Kunde gefunden wurde -> Weiter in das Kundenmenue
			if (found == null) {
				System.out.println("Logindaten Inkorrekt!");
			} else {
				System.out.println("Login Erfolgreich!");
				System.out.println("Hallo " + found.getFirstname() + " "
						+ found.getLastname());
				System.out.println("");
				showCustomerMenu(found);
			}
		}
	}

	/**
	 * CUI-Methode zur Ueberpruefung der Logindaten eines Mitarbeiters und
	 * weiterleiten in das Mitarbeitermenue
	 */
	public void loginEmployee() {
		Employee found = null;
		String user = "";
		String pw = "";
		while (found == null) {
			System.out.println("Bitte Mitarbeiter-ID eingeben:");
			try {
				user = console.readLine();
			} catch (IOException e) {
				e.printStackTrace();
			}
			System.out.println("Bitte Passwort eingeben:");
			try {
				pw = console.readLine();
			} catch (IOException e) {
				e.printStackTrace();
			}

			found = shopManager.loginEmployee(user, pw);

			if (found == null) {
				System.out.println("Logindaten Inkorrekt!");
			} else {
				System.out.println("Login Erfolgreich!");
				System.out.println("Hallo " + found.getFirstname() + " "
						+ found.getLastname());
				System.out.println("");
				showEmployeeMenu(found);
			}
		}
	}

	/**
	 * 
	 * CUI-Methode: Mitarbeitermenue
	 * 
	 * @param e
	 *            : Weitergabe des Mitarbeiter-Objekts
	 */
	public void showEmployeeMenu(Employee e) {
		String input = "";
		System.out.println("------------");
		System.out.println("(1) Artikelbestaende einsehen");
		System.out.println("(2) Artikel hinzufuegen");
		System.out.println("(3) Artikel veraendern");
		System.out.println("(4) Artikel loeschen");
		System.out.println("(5) Logout!");
		try {
			input = console.readLine();
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		// Alle Artikel anzeigen
		if (input.equals("1")) {
			ArrayList<Article> list = shopManager.getArticleManagement()
					.getArticleList();
			for (Article article : list) {
				System.out.println("ID: " + article.getId());
				System.out.println("Typ: " + article.getType());
				System.out.println("Name: " + article.getName());
				System.out.println("Beschreibung: " + article.getDescription());
				System.out.println("Bestand: " + article.getStock());
				System.out.println("Groesse: " + article.getSize());
				System.out.println("Farbe: " + article.getColor());
				System.out.println("Preis: " + article.getPrice());
			}
			showEmployeeMenu(e);
		} else if (input.equals("2")) {
			// Artikel hinzufuegen!
			String name = "";
			String description = "";
			String stock = "";
			String size = "";
			String price = "";
			String color = "";
			String type = "";
			String kind = "";
			int minCount = 1;
			boolean ok = false;

			do {
				try {
					System.out
							.println("Welche Art des Artikels wollen Sie anlegen?");
					System.out.println("(1) Einzelartikel");
					System.out.println("(2) Massenartikel");
					kind = console.readLine();

					if (kind.equals("2")) {

						System.out.println("Geben Sie die Losgr����e an:");
						minCount = Integer.parseInt(console.readLine());
					}

					System.out.println("Typ:");
					type = console.readLine();
					System.out.println("Name:");
					name = console.readLine();
					System.out.println("Beschreibung:");
					description = console.readLine();
					System.out.println("Bestand:");
					stock = console.readLine();
					System.out.println("Gr��sse:");
					size = console.readLine();
					System.out.println("Preis:");
					price = console.readLine();
					System.out.println("Farbe:");
					color = console.readLine();

					int stockInt = Integer.parseInt(stock);
					float priceFloat = Float.parseFloat(price);

					Article art = shopManager.addNewArticle(e, name,
							description, stockInt, size, priceFloat, color,
							type, minCount);

					// aktuellen Zeitstempel errechnen
					ok = true;

					System.out.println("Artikel erfolgreich angelegt.");
					showEmployeeMenu(e);
				} catch (IOException e1) {
					// e1.printStackTrace();
				} catch (WrongInputException e1) {
					System.out.println(e1.getMessage());
					// e1.printStackTrace();
				} catch (WrongMinCountException e1) {
					System.out.println(e1.getMessage());
				}

			} while (!ok);
		} else if (input.equals("3")) {
			ArrayList<Article> list = shopManager.getArticleManagement()
					.getArticleList();
			for (Article article : list) {
				System.out.println("ID: " + article.getId());
				System.out.println("Name: " + article.getName());
			}
			// Artikel veraendern!
			try {
				System.out.println("Bitte Artikelnr. eingeben:");
				String in = console.readLine();
				Article article = null;
				try {
					article = shopManager.getArticleManagement()
							.getArticleById(Long.parseLong(in));
				} catch (Exception e1) {
					e1.printStackTrace();
				}

				System.out.println("Was moechten sie veraendern?");
				System.out.println("(1) Bestand (" + article.getStock() + ")");
				System.out.println("(2) Preis (" + article.getPrice() + ")");
				int changeInput = Integer.parseInt(console.readLine());
				boolean ok = false;

				// TODO: AUSLAGERN!

				switch (changeInput) {
				case 1:
					System.out.println("Aktueller Bestand: "
							+ article.getStock());
					while (!ok) {
						System.out.print("Bitte neuen Wert eingeben:");
						in = console.readLine();
						ok = shopManager.checkNumeric(in);
					}

					int newVal = Integer.parseInt(in);
					article.setStock(newVal);

					shopManager.log(e, article, newVal, "veraendert");

					break;
				case 2:
					System.out
							.println("Aktueller Preis: " + article.getPrice());
					while (!ok) {
						System.out.print("Bitte neuen Wert eingeben:");
						in = console.readLine();
						ok = shopManager.checkNumeric(in);
					}
					article.setPrice(Float.parseFloat(in));
					break;
				default:
					break;
				}
			} catch (NumberFormatException e1) {
				e1.printStackTrace();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
			
			// Shop speichern
			shopManager.saveDB();
			showEmployeeMenu(e);
			
			// Artikel l��schen
		} else if (input.equals("4")) {
			System.out.println("Welcher Artikel soll geloescht werden?");
			try {
				String in = console.readLine();
				long inLong = Long.valueOf(in);
				
				Article article = shopManager.getArticleManagement().getArticleById(inLong);
				
				shopManager.deleteArticle(e,article);
				
			} catch (IOException e1) {
				e1.printStackTrace();
			} catch (ArticleNotFoundException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		} else if (input.equals("5")) {
			System.out.println("Ausgeloggt...");
			selectUserType();
		}
	}

	/**
	 * 
	 * CUI-Methode: Mitarbeiter-Menue
	 * 
	 * @param customer
	 */
	public void showCustomerMenu(Customer customer) {
		String input = "";
		System.out.println("------------");
		System.out.println("(1) Einkaufen");
		System.out.println("(2) Warenkorb ansehen");
		System.out.println("(3) Zur Kasse gehen");
		System.out.println("(4) Logout!");
		try {
			input = console.readLine();
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		if (input.equals("1")) {
			ArrayList<Article> articleList = shopManager.getArticleManagement()
					.getArticleList();
			for (Article article : articleList) {
				System.out.println("(" + article.getId() + ") "
						+ article.getName());
				System.out.println(article.getPrice() + " Euro");

				if (article instanceof MassArticle) {
					MassArticle ma = (MassArticle) article;
					System.out
							.println("Massenartikel (Artikel kann nur als Vielfaches von "
									+ ma.getMinCount() + " gekauft werden");
				}
			}

			boolean okay = false;

			do {
				try {

					System.out
							.print("Bitte die gewuenschte Artikelnummer eingeben:");
					String buy = console.readLine();

					Article article = shopManager.getArticleManagement()
							.getArticleById(Long.parseLong(buy));

					okay = true;

					System.out.print("Und die Anzahl:");
					String count = console.readLine();

					// Artikel in WK legen!
					shopManager.addToCart(customer, article,
							Integer.parseInt(count));

					System.out.println("Erfolgreich in den Warenkorb gelegt!");

					showCustomerMenu(customer);

				} catch (ArticleNotFoundException e) {
					// e.printStackTrace();
					System.out.println(e.getMessage());
					System.out.println("Ueberpruefen Sie die Artikelnummer!");
				} catch (StockTooLowException e) {
					e.printStackTrace();
					System.out.println(e.getMessage());
				} catch (IOException e) {
					e.printStackTrace();
				} catch (NumberFormatException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (WrongMinCountException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

			} while (!okay);

		} else if (input.equals("2")) {
			String[] types = { "T-Shirt", "Hose", "Sweatshirt", "Jacke",
					"Hemd", "Bluse", "Schuh", "Accessoire" };

			for (String string : types) {
				for (Article article : customer.getCart().getList().keySet()) {
					if (article.getType().equals(string)) {
						System.out.println("-----");
						System.out.println("ID: " + article.getId());
						System.out.println("Name: " + article.getName());
						System.out.println("Typ: " + article.getType());
						System.out.println("Beschreibung: "
								+ article.getDescription());
						System.out.println("Groesse: " + article.getSize());
						System.out.println("Farbe: " + article.getColor());
						System.out.println("Preis: " + article.getPrice());
						System.out.println("Anzahl: "
								+ customer.getCart().getList().get(article)
										.intValue());

						if (article instanceof MassArticle) {
							MassArticle ma = (MassArticle) article;
							System.out.println("Massenartikel Losgr����e: "
									+ ma.getMinCount());
						}

						System.out.println("-----");
						System.out.println();
					}
				}
			}
			System.out.println("------------");
			System.out.println("(1) Bestand verandern");
			System.out.println("(2) Artikel entfernen");
			System.out.println("(3) Zurueck zum Menue");
			int in;
			try {
				in = Integer.parseInt(console.readLine());
				switch (in) {
				case 1:
					System.out.println("Welchen Artikel moechten Sie aendern?");
					long id = Long.parseLong(console.readLine());
					System.out.println("Um welchen Wert?");
					int count = Integer.parseInt(console.readLine());
					
					shopManager.editCartStock(customer, id, count);
					
					break;
				case 2:
					System.out
							.println("Welchen Artikel moechten Sie entfernen?");
					long id2 = Long.parseLong(console.readLine());
					try {
						
						shopManager.removeArticleFromCart(customer,id2);
						
					} catch (EmptyCartException e) {
						System.out.println(e.getMessage());
					}
				case 3:
					showCustomerMenu(customer);
					break;
				default:
					break;
				}
				showCustomerMenu(customer);
			} catch (NumberFormatException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} catch (WrongMinCountException e1) {
				// TODO Auto-generated catch block
				System.out.println(e1.getMessage());
			} catch (ArticleNotFoundException e1) {
				// TODO Auto-generated catch block
				System.out.println(e1.getMessage());
			} catch (StockTooLowException e1) {
				System.out.println(e1.getMessage());
			}
		} else if (input.equals("3")) {

			Invoice invoice;
			try {
				
				invoice = shopManager.buy(customer);

				// HASHTABLE KLONEN um doppeltes Speichern zu vermeiden!...
				if (invoice != null) {
					showInvoice(invoice);
				} else {
					System.out
							.println("Leider gab es einen Fehler beim bezahlen");
				}
				showCustomerMenu(customer);

			} catch (EmptyCartException e) {
				// TODO Auto-generated catch block
				System.out.println(e.getMessage());
				showCustomerMenu(customer);
			}

		} else if (input.equals("4")) {
			System.out.println("Ausgeloggt...");
			selectUserType();
		}
	}

	public void showLog() {
		LogManagement logger = shopManager.getLogger();
		ArrayList<Log> list = logger.getLogList();
		String c = "(K)";

		for (Log log : list) {
			if (log.getActor() instanceof Employee) {
				c = "(M)";
			}
			System.out.println("["+log.getTimestamp()+"] "+log.getActor().getLastname() + c + " hat "
					+ log.getArticle().getName() + " " + log.getCount()
					+ " mal " + log.getWhat());
		}
	}

	public void showInvoice(Invoice invoice) {

		Customer c = shopManager.getCustomerManagement().getCustomerById(
				invoice.getCustomerID());

		System.out.println("--------- Rechnung ----------");
		System.out.println();
		System.out.println("Rechnungsnummer: " + invoice.getInvoiceNumber());
		System.out.println("Kundennummer: " + invoice.getCustomerID());
		System.out.println();
		System.out.println(c.getFirstname() + " " + c.getLastname());
		System.out.println(c.getStreet());
		System.out.println(c.getZip() + " " + c.getCity());
		System.out.println();
		System.out.println();

		for (Article a : c.getCart().getList().keySet()) {
			int count = c.getCart().getList().get(a).intValue();
			float fullPrice = count * a.getPrice();
			System.out.println(a.getId() + "   " + a.getName() + "   " + count
					+ "   " + a.getPrice() + "   " + fullPrice);
		}
		System.out.println("Gesamtpreis: "
				+ c.getCart().getShoppingCartFullCosts());

		// Warenkorb leeren
		c.getCart().getList().clear();
		// Save
		shopManager.saveDB();
	}

	/**
	 * 
	 * Main-Methode
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		
		//GUI!
		
		new LoginMask();
		
		//CUI!
		//new MainShop().showLog();
		//new MainShop().selectUserType();
		// MainShop tst = new MainShop();
		// Article a = null;
		// try {
		// a = tst.shopManager.getArticleManagement().getArticleById(1);
		// } catch (ArticleNotFoundException e) {
		// // TODO Auto-generated catch block
		// e.printStackTrace();
		// }
		// int[] b = tst.shopManager.getLogger().getLogByArticleAndDays(a, 1);
		// for (int i : b) {
		// System.out.println(i);
		// }
	}
}